Skip to main content

Overview

The Order Management system is the core of Ai Studio’s operations, handling all customer orders from intake through fulfillment. The system supports three order types: pickup, delivery, and dine-in, with intelligent status tracking and payment verification.

Key Benefits

  • Multi-channel Order Intake: Accept orders from admin panel, web assistant (Slice), or WhatsApp bot
  • Real-time Status Tracking: Monitor orders through 10 distinct lifecycle states
  • Payment Verification: Track payment method and approval status before completion
  • Firebase Sync: All orders sync in real-time across devices and interfaces
  • Comprehensive History: Full audit trail with status timestamps

Order Types

The system supports three distinct order types, each with its own workflow:
Customers order ahead and collect at the restaurant.Payment Options: Cash or Credit (customer selects at order time)Typical Flow:
Pending → Confirmed → Preparing → Ready → Completed (Pickup)

Order Data Structure

Order Interface

From types.ts:87-108:
export interface Order {
  id: string;                          // Format: ORD-{timestamp}-{random}
  customer: {
    name: string;
    phone?: string;
    address?: string;                  // Required for delivery
  };
  items: OrderItem[];                  // Products in the order
  total: number;                       // Total price
  status: OrderStatus;                 // Current status
  type: OrderType;                     // pickup | delivery | dine-in
  createdAt: string;                   // ISO timestamp
  statusHistory: StatusHistory[];      // Full audit trail
  finishedAt: string | null;           // When order completed/cancelled
  tableIds?: string[];                 // For dine-in orders
  guests?: number;                     // Number of diners
  paymentMethod: PaymentMethod;        // Cash | Credit | Transfer
  isPaid: boolean;                     // Payment approval status
  paymentProofUrl?: string | null;     // Transfer receipt URL
  reservationId?: string;              // Link to reservation if applicable
  createdBy: CreatedBy;                // Admin | Web Assistant | WhatsApp
}

Order Item Structure

From types.ts:79-85:
export interface OrderItem {
  name: string;            // Product name
  quantity: number;        // How many
  price: number;          // Unit price
  isPromotion: boolean;   // Whether this is a promotion item
  itemId: string;         // Product or Promotion ID
}

Order Statuses

From types.ts:48-59, the system defines 10 order statuses:
export enum OrderStatus {
  PENDING = 'Pendiente',                              // Initial state
  CONFIRMED = 'Confirmado',                           // Order accepted
  PREPARING = 'En Preparación',                       // Kitchen working
  READY = 'Listo para Retirar/Entregar',             // Ready for next step
  DELIVERING = 'En Camino',                           // Delivery in progress
  DINE_IN_PENDING_PAYMENT = 'En Mesa (Pendiente de Pago)',  // Waiting for payment
  COMPLETED_PICKUP = 'Completado (Retirado)',        // Pickup completed
  COMPLETED_DELIVERY = 'Completado (Entregado)',     // Delivery completed
  COMPLETED_DINE_IN = 'Completado (En Mesa)',        // Dine-in completed
  CANCELLED = 'Cancelado',                            // Order cancelled
}
The system tracks finished orders as any status in: COMPLETED_PICKUP, COMPLETED_DELIVERY, COMPLETED_DINE_IN, or CANCELLED.

Payment Methods

From types.ts:67-71:
export enum PaymentMethod {
  CASH = 'Efectivo',
  CREDIT = 'Credito',
  TRANSFER = 'Transferencia',
}

Payment Rules

Critical Payment Validations:
  • Orders cannot be marked as completed unless isPaid: true
  • Delivery orders must use Transfer payment method
  • Pickup orders can use Cash or Credit
  • Dine-in orders accept all payment methods
  • Payment proof URL can be attached for transfers

Core Service Functions

From services/orderService.ts:

Creating Orders

saveOrder(
  orderData: Omit<Order, 'id' | 'status' | 'createdAt' | 'statusHistory' | 'finishedAt' | 'isPaid'>
): Promise<Order>
Example Usage:
import { saveOrder } from './services/orderService';
import { OrderType, PaymentMethod, CreatedBy } from './types';

const newOrder = await saveOrder({
  customer: {
    name: 'Juan Pérez',
    phone: '1234567890',
    address: 'Calle Falsa 123'
  },
  items: [
    {
      name: 'Pizza Muzzarella',
      quantity: 2,
      price: 9200,
      isPromotion: false,
      itemId: 'PROD-123'
    }
  ],
  total: 18400,
  type: OrderType.DELIVERY,
  paymentMethod: PaymentMethod.TRANSFER,
  createdBy: CreatedBy.ADMIN,
});

// Returns order with:
// - Auto-generated ID (ORD-{timestamp}-{random})
// - status: PENDING
// - isPaid: false (unless paymentProofUrl provided)
// - statusHistory initialized

Updating Order Status

updateOrderStatus(
  orderId: string,
  status: OrderStatus
): Promise<Order>
Example:
import { updateOrderStatus } from './services/orderService';
import { OrderStatus } from './types';

// Move order to next stage
const updatedOrder = await updateOrderStatus(
  'ORD-1234567890-abc',
  OrderStatus.PREPARING
);

// System automatically:
// - Adds status to statusHistory with timestamp
// - Sets finishedAt if moving to completed/cancelled status
// - Creates notification for status change
// - Syncs to Firebase
Status Transition Rules:
  • Cannot change status of already-finished orders
  • Cannot complete order unless isPaid: true
  • Completing order automatically sets isPaid: true (except for cancelled)

Managing Payment Status

markOrderAsPaid(
  orderId: string,
  paymentMethod: PaymentMethod,
  paymentProofUrl?: string | null
): Promise<Order>
Example:
import { markOrderAsPaid } from './services/orderService';
import { PaymentMethod } from './types';

// Record payment for delivery order
const paidOrder = await markOrderAsPaid(
  'ORD-1234567890-abc',
  PaymentMethod.TRANSFER,
  'https://storage.example.com/receipt123.jpg'
);

// For dine-in orders at DINE_IN_PENDING_PAYMENT:
// - Automatically transitions to COMPLETED_DINE_IN
// - Adds completion to statusHistory

Retrieving Orders

// Get all orders from cache (sorted newest first)
getOrdersFromCache(): Order[]

// Fetch latest from Firebase and update cache
fetchAndCacheOrders(): Promise<Order[]>

// Check if order is finished
isOrderFinished(status: OrderStatus): boolean

User Workflows

Admin Creating an Order

1

Navigate to Orders Panel

From the admin sidebar, click “Orders” to view the OrdersPanel.
2

Click 'Nuevo Pedido'

Opens order creation form with fields for customer, items, and order details.
3

Select Order Type

Choose Pickup, Delivery, or Dine-In. This determines:
  • Required fields (address for delivery, tables for dine-in)
  • Available payment methods
  • Status workflow
4

Add Items

Select products from the menu, specify quantities. System calculates total automatically.
5

Enter Customer Details

Name, phone, and address (if delivery). System may auto-suggest from customer database.
6

Select Payment Method

Based on order type:
  • Delivery: Transfer (can upload payment proof)
  • Pickup: Cash or Credit
  • Dine-In: Any method (paid later)
7

Submit Order

Order created with status PENDING. Notification sent. Firebase sync immediate.

Processing Orders Through Kitchen

1

Confirm Order

Admin reviews order, clicks “Confirmar” → Status: CONFIRMED
2

Start Preparation

Kitchen begins work, admin updates → Status: PREPARING
3

Mark as Ready

Order complete, admin marks ready → Status: READY
4

Final Step (varies by type)

  • Pickup: Customer arrives → COMPLETED_PICKUP
  • Delivery: Driver dispatched → DELIVERING → COMPLETED_DELIVERY
  • Dine-In: Customer finishes → DINE_IN_PENDING_PAYMENT → (after payment) → COMPLETED_DINE_IN

AI Assistant Order Flow

From components/ChatAssistantModal.tsx and services/geminiService.ts:
1

Customer Opens Chat

Slice AI assistant greets customer, asks if they want to order or make a reservation.
2

Customer Requests Order

System sets actionLock: 'order' to focus conversation on ordering.
3

Gather Order Details

AI collects:
  • Products and quantities from menu
  • Delivery or pickup
  • Customer name and phone
  • Address (if delivery)
  • Payment method (Transfer for delivery, Cash/Credit for pickup)
4

AI Confirms Details

Presents summary, asks for explicit confirmation.
5

Generate Order JSON

After confirmation, AI responds with structured JSON:
{
  "intent": "ORDER",
  "customer": { "name": "...", "phone": "...", "address": "..." },
  "items": [...],
  "total": 9200,
  "type": "delivery",
  "paymentMethod": "Transferencia"
}
6

System Creates Order

saveOrder() called with createdBy: WEB_ASSISTANT. Order appears in admin panel immediately.

Real-Time Synchronization

From components/AdminDashboard.tsx:106-132: Orders sync in real-time via Firebase listeners:
// Admin dashboard subscribes to Orders collection
const unsubOrders = onSnapshot(
  collection(db, 'Orders'),
  (querySnapshot) => {
    const items = querySnapshot.docs.map(doc => doc.data() as Order);
    updateOrdersCache(items);
    setDataTimestamp(Date.now()); // Triggers UI refresh
  }
);
Benefits:
  • Multi-device admin access (changes appear instantly on all devices)
  • AI assistants create orders that appear immediately in admin panel
  • No manual refresh needed
  • Offline-first with localStorage fallback

Notifications

From components/AdminDashboard.tsx:175-187: The system automatically generates notifications for:
  • New Orders: When first order arrives or latest order changes
  • Status Changes: Each status transition creates a notification
// Auto-notification on new order
if (currentOrders[0].id !== lastCheckedOrder.current) {
  addNotification({
    message: `Nuevo pedido de ${currentOrders[0].customer.name} por $${currentOrders[0].total}`,
    type: 'order',
    relatedId: currentOrders[0].id,
  });
}

Order History & Audit Trail

Every status change is recorded in statusHistory:
export interface StatusHistory {
  status: OrderStatus;
  startedAt: string;  // ISO timestamp
}
Example status history:
[
  { "status": "Pendiente", "startedAt": "2026-03-10T14:30:00.000Z" },
  { "status": "Confirmado", "startedAt": "2026-03-10T14:32:15.000Z" },
  { "status": "En Preparación", "startedAt": "2026-03-10T14:35:00.000Z" },
  { "status": "Listo para Retirar/Entregar", "startedAt": "2026-03-10T14:50:00.000Z" },
  { "status": "Completado (Retirado)", "startedAt": "2026-03-10T15:05:00.000Z" }
]

Configuration

Order Type Enum

From types.ts:61-65:
export enum OrderType {
  PICKUP = 'pickup',
  DELIVERY = 'delivery',
  DINE_IN = 'dine-in',
}

Creation Source Tracking

From types.ts:73-77:
export enum CreatedBy {
  ADMIN = 'Admin Panel',
  WEB_ASSISTANT = 'Web Assistant',      // Slice chat
  WHATSAPP_ASSISTANT = 'WhatsApp Assistant',
}

Best Practices

Always Verify Payment

Before marking an order as completed, ensure isPaid: true. The system enforces this rule.

Use Correct Payment Methods

Delivery must use Transfer. Pickup allows Cash/Credit. Dine-in accepts all methods.

Track Order Source

Use createdBy to understand which channel generated the order for analytics.

Leverage Status History

Use statusHistory for analytics, customer service, and performance tracking.